        <!DOCTYPE html>
        <html>
        <head>
                <meta charset="utf-8">
        <title>RevoluteJoint class / box2d Library / Dart Documentation</title>
        <link rel="stylesheet" type="text/css"
            href="../styles.css">
        <link href="http://fonts.googleapis.com/css?family=Open+Sans:400,600,700,800" rel="stylesheet" type="text/css">
        <link rel="shortcut icon" href="../favicon.ico">
        
        </head>
        <body data-library="box2d" data-type="RevoluteJoint">
        <div class="page">
        <div class="header">
          <a href="../index.html"><div class="logo"></div></a>
          <a href="../index.html">Dart Documentation</a>
         &rsaquo; <a href="../box2d.html">box2d</a> &rsaquo; <a href="../box2d/RevoluteJoint.html">RevoluteJoint</a>        <div id="search-box">
          <input type="search" name="q" id="q" autocomplete="off"
              class="search-input" placeholder="Search API">
        </div>
        
      </div>
      <div class="drop-down" id="drop-down"></div>
      
        <div class="nav">
        
</div>
<div class="content">
        <h2><strong>RevoluteJoint</strong>
          class
        </h2>
        
<button id="show-inherited" class="show-inherited">Hide inherited</button>
<div class="doc">
<pre class="source">
class RevoluteJoint extends Joint {
 final vec2 localAnchor1;
 final vec2 localAnchor2;

 final vec3 impulse;

 num _motorImpulse;

 // Effective mass for point-to-point constraint.
 final mat3 mass;

 // Effective mass for motor/limit angular constraint.
 num motorMass;

 bool _enableMotor;

 num _maxMotorTorque;

 num _motorSpeed;

 bool _enableLimit;

 num referenceAngle;

 /** Limits on the relative rotation of the joint. */
 num lowerAngle;
 num upperAngle;

 int limitState;

 RevoluteJoint(RevoluteJointDef def) :
   super(def),
   localAnchor1 = new vec2.zero(),
   localAnchor2 = new vec2.zero(),
   impulse = new vec3.zero(),
   _motorImpulse = 0,
   mass = new mat3.zero() {
   localAnchor1.copyFrom(def.localAnchorA);
   localAnchor2.copyFrom(def.localAnchorB);
   referenceAngle = def.referenceAngle;

   _motorImpulse = 0;

   lowerAngle = def.lowerAngle;
   upperAngle = def.upperAngle;
   _maxMotorTorque = def.maxMotorTorque;
   _motorSpeed = def.motorSpeed;
   _enableLimit = def.enableLimit;
   _enableMotor = def.enableMotor;
 }

 void initVelocityConstraints(TimeStep time_step) {
   final Body b1 = bodyA;
   final Body b2 = bodyB;

   if (_enableMotor || _enableLimit) {
     // You cannot create a rotation limit between bodies that
     // both have fixed rotation.
     assert (b1.invInertia &gt; 0.0 || b2.invInertia &gt; 0.0);
   }

   // Compute the effective mass matrix.
   final vec2 r1 = localAnchor1 - b1.localCenter;
   final vec2 r2 = localAnchor2 - b2.localCenter;
   b1.originTransform.rotation.transform(r1);
   b2.originTransform.rotation.transform(r2);

   num m1 = b1.invMass, m2 = b2.invMass;
   num i1 = b1.invInertia, i2 = b2.invInertia;

   mass.col0.x = m1 + m2 + r1.y * r1.y * i1 + r2.y * r2.y * i2;
   mass.col1.x = -r1.y * r1.x * i1 - r2.y * r2.x * i2;
   mass.col2.x = -r1.y * i1 - r2.y * i2;
   mass.col0.y = mass.col1.x;
   mass.col1.y = m1 + m2 + r1.x * r1.x * i1 + r2.x * r2.x * i2;
   mass.col2.y = r1.x * i1 + r2.x * i2;
   mass.col0.z = mass.col2.x;
   mass.col1.z = mass.col2.y;
   mass.col2.z = i1 + i2;

   motorMass = i1 + i2;
   if (motorMass &gt; 0.0) {
     motorMass = 1.0 / motorMass;
   }

   if (_enableMotor == false) {
     _motorImpulse = 0.0;
   }

   if (_enableLimit) {
     num jointAngle = b2.sweep.angle - b1.sweep.angle - referenceAngle;
     if ((upperAngle - lowerAngle).abs() &lt; 2.0 * Settings.ANGULAR_SLOP) {
       limitState = LimitState.EQUAL;
     }
     else if (jointAngle &lt;= lowerAngle) {
       if (limitState != LimitState.AT_LOWER) {
         impulse.z = 0.0;
       }
       limitState = LimitState.AT_LOWER;
     }
     else if (jointAngle &gt;= upperAngle) {
       if (limitState != LimitState.AT_UPPER) {
         impulse.z = 0.0;
       }
       limitState = LimitState.AT_UPPER;
     }
     else {
       limitState = LimitState.INACTIVE;
       impulse.z = 0.0;
     }
   }
   else {
     limitState = LimitState.INACTIVE;
   }

   if (time_step.warmStarting) {
     // Scale impulses to support a variable time time_step.
     impulse.scale(time_step.dtRatio);
     _motorImpulse *= time_step.dtRatio;

     vec2 P = new vec2.copy(impulse.xy);

     vec2 temp = new vec2.copy(P);
     temp.scale(m1);
     b1.linearVelocity.sub(temp);
     b1.angularVelocity -= i1 * (cross(r1, P) + _motorImpulse + impulse.z);

     temp.copyFrom(P).scale(m2);
     b2.linearVelocity.add(temp);
     b2.angularVelocity += i2 * (cross(r2, P) + _motorImpulse + impulse.z);

   } else {
     impulse.splat(0.0);
     _motorImpulse = 0.0;
   }
 }

 void solveVelocityConstraints(final TimeStep time_step) {
   final Body b1 = bodyA;
   final Body b2 = bodyB;

   final vec2 v1 = b1.linearVelocity;
   num w1 = b1.angularVelocity;
   final vec2 v2 = b2.linearVelocity;
   num w2 = b2.angularVelocity;

   num m1 = b1.invMass, m2 = b2.invMass;
   num i1 = b1.invInertia, i2 = b2.invInertia;

   // Solve motor constraint.
   if (_enableMotor &amp;&amp; limitState != LimitState.EQUAL) {
     num Cdot = w2 - w1 - _motorSpeed;
     num imp = motorMass * (-Cdot);
     num oldImpulse = _motorImpulse;
     num maxImpulse = time_step.dt * _maxMotorTorque;
     _motorImpulse = clamp(_motorImpulse + imp, -maxImpulse, maxImpulse);
     imp = _motorImpulse - oldImpulse;

     w1 -= i1 * imp;
     w2 += i2 * imp;
   }

   vec2 temp = new vec2.zero();

   // Solve limit constraint.
   if (_enableLimit &amp;&amp; limitState != LimitState.INACTIVE) {

     final vec2 r1 = localAnchor1 - b1.localCenter;
     final vec2 r2 = localAnchor2 - b2.localCenter;
     b1.originTransform.rotation.transform(r1);
     b2.originTransform.rotation.transform(r2);

     // Solve point-to-point constraint
     cross(w1, r1, temp);
     final vec2 Cdot1 = cross(w2, r2);
     Cdot1.add(v2).sub(v1).sub(temp);
     num Cdot2 = w2 - w1;
     vec3 Cdot = new vec3(Cdot1.x, Cdot1.y, Cdot2);

     vec3 imp = MathBox.solve33(mass, Cdot.negate());

     if (limitState == LimitState.EQUAL) {
       impulse.add(imp);
     }
     else if (limitState == LimitState.AT_LOWER) {
       num newImpulse = impulse.z + imp.z;
       if (newImpulse &lt; 0.0) {
         temp = MathBox.solve22(mass, Cdot1.negate());
         imp.x = temp.x;
         imp.y = temp.y;
         imp.z = -impulse.z;
         impulse.x += temp.x;
         impulse.y += temp.y;
         impulse.z = 0.0;
       }
     } else if (limitState == LimitState.AT_UPPER) {
       num newImpulse = impulse.z + imp.z;
       if (newImpulse &gt; 0.0) {
         temp = MathBox.solve22(mass, Cdot1.negate());
         imp.x = temp.x;
         imp.y = temp.y;
         imp.z = -impulse.z;
         impulse.x += temp.x;
         impulse.y += temp.y;
         impulse.z = 0.0;
       }
     }
     final vec2 P = new vec2.copy(imp.xy);

     temp.copyFrom(P).scale(m1);
     v1.sub(temp);
     w1 -= i1 * (cross(r1, P) + imp.z);

     temp.copyFrom(P).scale(m2);
     v2.add(temp);
     w2 += i2 * (cross(r2, P) + imp.z);

   } else {
     final vec2 r1 = localAnchor1 - b1.localCenter;
     final vec2 r2 = localAnchor2 - b2.localCenter;
     b1.originTransform.rotation.transform(r1);
     b2.originTransform.rotation.transform(r2);

     // Solve point-to-point constraint
     cross(w1, r1, temp);
     vec2 Cdot = cross(w2, r2);
     Cdot.add(v2).sub(v1).sub(temp);
     vec2 imp = MathBox.solve22(mass, Cdot.negate()); // just leave negated

     impulse.x += imp.x;
     impulse.y += imp.y;

     temp.copyFrom(imp).scale(m1);
     v1.sub(temp);
     w1 -= i1 * cross(r1, imp);

     temp.copyFrom(imp).scale(m2);
     v2.add(temp);
     w2 += i2 * cross(r2, imp);
   }

   b1.angularVelocity = w1;
   b2.angularVelocity = w2;
 }

 bool solvePositionConstraints(num baumgarte) {
   final Body b1 = bodyA;
   final Body b2 = bodyB;

   num angularError = 0.0;
   num positionError = 0.0;

   // Solve angular limit constraint.
   if (_enableLimit &amp;&amp; limitState != LimitState.INACTIVE) {
     num angle = b2.sweep.angle - b1.sweep.angle - referenceAngle;
     num limitImpulse = 0.0;

     if (limitState == LimitState.EQUAL) {
       // Prevent large angular corrections
       num C = clamp(angle - lowerAngle, -Settings.MAX_ANGULAR_CORRECTION, Settings.MAX_ANGULAR_CORRECTION);
       limitImpulse = -motorMass * C;
       angularError = C.abs();
     } else if (limitState == LimitState.AT_LOWER) {
       num C = angle - lowerAngle;
       angularError = -C;

       // Prevent large angular corrections and allow some slop.
       C = clamp(C + Settings.ANGULAR_SLOP, -Settings.MAX_ANGULAR_CORRECTION, 0.0);
       limitImpulse = -motorMass * C;
     } else if (limitState == LimitState.AT_UPPER) {
       num C = angle - upperAngle;
       angularError = C;

       // Prevent large angular corrections and allow some slop.
       C = clamp(C - Settings.ANGULAR_SLOP, 0.0, Settings.MAX_ANGULAR_CORRECTION);
       limitImpulse = -motorMass * C;
     }

     b1.sweep.angle -= b1.invInertia * limitImpulse;
     b2.sweep.angle += b2.invInertia * limitImpulse;

     b1.synchronizeTransform();
     b2.synchronizeTransform();
   }

   // Solve point-to-point constraint.
   {
     vec2 imp = new vec2.zero();

     final vec2 r1 = localAnchor1 - b1.localCenter;
     final vec2 r2 = localAnchor2 - b2.localCenter;
     b1.originTransform.rotation.transform(r1);
     b2.originTransform.rotation.transform(r2);

     final vec2 C = b2.sweep.center + r2 - (b1.sweep.center + r1);
     positionError = C.length;

     num invMass1 = b1.invMass, invMass2 = b2.invMass;
     num invI1 = b1.invInertia, invI2 = b2.invInertia;

     // Handle large detachment.
     final num k_allowedStretch = 10.0 * Settings.LINEAR_SLOP;
     if (C.length2 &gt; k_allowedStretch * k_allowedStretch) {
       vec2 u = new vec2.zero();

       // Use a particle solution (no rotation).
       num m = invMass1 + invMass2;
       if (m &gt; 0.0) {
         m = 1.0 / m;
       }
       imp.copyFrom(C).negate().scale(m);
       final num k_beta = 0.5;
       // using u as temp variable
       u.copyFrom(imp).scale(k_beta * invMass1);
       b1.sweep.center.sub(u);
       u.copyFrom(imp).scale(k_beta * invMass2);
       b2.sweep.center.add(u);

       C.copyFrom(b2.sweep.center).add(r2);
       C.sub(b1.sweep.center).sub(r1);
     }

     mat2 K1 = new mat2.zero();
     K1.col0.x = invMass1 + invMass2;
     K1.col1.x = 0.0;
     K1.col0.y = 0.0;
     K1.col1.y = invMass1 + invMass2;

     mat2 K2 = new mat2.zero();
     K2.col0.x = invI1 * r1.y * r1.y;
     K2.col1.x = -invI1 * r1.x * r1.y;
     K2.col0.y = -invI1 * r1.x * r1.y;
     K2.col1.y = invI1 * r1.x * r1.x;

     mat2 K3 = new mat2.zero();
     K3.col0.x = invI2 * r2.y * r2.y;
     K3.col1.x = -invI2 * r2.x * r2.y;
     K3.col0.y = -invI2 * r2.x * r2.y;
     K3.col1.y = invI2 * r2.x * r2.x;

     K1.add(K2).add(K3);
     imp = MathBox.solve22(K1, C.negate()); // just leave c negated

     // using C as temp variable
     C.copyFrom(imp).scale(b1.invMass);
     b1.sweep.center.sub(C);
     b1.sweep.angle -= b1.invInertia * cross(r1, imp);

     C.copyFrom(imp).scale(b2.invMass);
     b2.sweep.center.add(C);
     b2.sweep.angle += b2.invInertia * cross(r2, imp);

     b1.synchronizeTransform();
     b2.synchronizeTransform();
   }

   return positionError &lt;= Settings.LINEAR_SLOP &amp;&amp; angularError &lt;=
       Settings.ANGULAR_SLOP;
 }

 void getAnchorA(vec2 argOut) {
   bodyA.getWorldPointToOut(localAnchor1, argOut);
 }

 void getAnchorB(vec2 argOut) {
   bodyB.getWorldPointToOut(localAnchor2, argOut);
 }

 void getReactionForce(num inv_dt, vec2 argOut) {
   argOut.setComponents(impulse.x, impulse.y).scale(inv_dt);
 }

 num getReactionTorque(num inv_dt) {
   return inv_dt * impulse.z;
 }

 num get jointAngle {
   final Body b1 = bodyA;
   final Body b2 = bodyB;
   return b2.sweep.angle - b1.sweep.angle - referenceAngle;
 }

 num get jointSpeed {
   final Body b1 = bodyA;
   final Body b2 = bodyB;
   return b2.angularVelocity - b1.angularVelocity;
 }

 bool get motorEnabled =&gt; _enableMotor;

 void set motorEnabled(bool flag) {
   bodyA.awake = true;
   bodyB.awake = true;
   _enableMotor = flag;
 }

 num get motorTorque =&gt; _motorImpulse;

 void set motorSpeed(num speed) {
   bodyA.awake = true;
   bodyB.awake = true;
   _motorSpeed = speed;
 }

 num get motorSpeed =&gt; _motorSpeed;

 num get maxMotorTorque =&gt; _maxMotorTorque;

 void set maxMotorTorque(num torque) {
   bodyA.awake = true;
   bodyB.awake = true;
   _maxMotorTorque = torque;
 }

 bool get limitEnabled =&gt; _enableLimit;

 void set limitEnabled(bool flag) {
   bodyA.awake = true;
   bodyB.awake = true;
   _enableLimit = flag;
 }

 void setLimits(final num lower, final num upper) {
   assert (lower &lt;= upper);
   bodyA.awake = true;
   bodyB.awake = true;
   lowerAngle = lower;
   upperAngle = upper;
 }
}
</pre>
</div>
<h3>Extends</h3>
<p>
<span class="type-box"><span class="icon-class"></span><a href="../box2d/Joint.html">Joint</a></span>&nbsp;&gt;&nbsp;<span class="type-box"><span class="icon-class"></span><strong>RevoluteJoint</strong></span></p>
<div>
<h3>Constructors</h3>
<div class="method"><h4 id="RevoluteJoint">
<button class="show-code">Code</button>
new <strong>RevoluteJoint</strong>(<a href="../box2d/RevoluteJointDef.html">RevoluteJointDef</a> def) <a class="anchor-link" href="#RevoluteJoint"
              title="Permalink to RevoluteJoint.RevoluteJoint">#</a></h4>
<div class="doc">
<pre class="source">
RevoluteJoint(RevoluteJointDef def) :
 super(def),
 localAnchor1 = new vec2.zero(),
 localAnchor2 = new vec2.zero(),
 impulse = new vec3.zero(),
 _motorImpulse = 0,
 mass = new mat3.zero() {
 localAnchor1.copyFrom(def.localAnchorA);
 localAnchor2.copyFrom(def.localAnchorB);
 referenceAngle = def.referenceAngle;

 _motorImpulse = 0;

 lowerAngle = def.lowerAngle;
 upperAngle = def.upperAngle;
 _maxMotorTorque = def.maxMotorTorque;
 _motorSpeed = def.motorSpeed;
 _enableLimit = def.enableLimit;
 _enableMotor = def.enableMotor;
}
</pre>
</div>
</div>
</div>
<div>
<h3>Properties</h3>
<div class="field inherited"><h4 id="active">
<button class="show-code">Code</button>
final bool         <strong>active</strong> <a class="anchor-link"
            href="#active"
            title="Permalink to RevoluteJoint.active">#</a>
        </h4>
        <div class="inherited-from">inherited from <a href="../box2d/Joint.html">Joint</a> </div><div class="doc">
<p>Short-cut function to determine if either body is inactive. </p>
<pre class="source">
bool get active =&gt; bodyA.active &amp;&amp; bodyB.active;
</pre>
</div>
</div>
<div class="field inherited"><h4 id="bodyA">
<button class="show-code">Code</button>
<a href="../box2d/Body.html">Body</a>         <strong>bodyA</strong> <a class="anchor-link"
            href="#bodyA"
            title="Permalink to RevoluteJoint.bodyA">#</a>
        </h4>
        <div class="inherited-from">inherited from <a href="../box2d/Joint.html">Joint</a> </div><div class="doc">
<pre class="source">
bodyA
</pre>
</div>
</div>
<div class="field inherited"><h4 id="bodyB">
<button class="show-code">Code</button>
<a href="../box2d/Body.html">Body</a>         <strong>bodyB</strong> <a class="anchor-link"
            href="#bodyB"
            title="Permalink to RevoluteJoint.bodyB">#</a>
        </h4>
        <div class="inherited-from">inherited from <a href="../box2d/Joint.html">Joint</a> </div><div class="doc">
<pre class="source">
bodyB
</pre>
</div>
</div>
<div class="field inherited"><h4 id="collideConnected">
<button class="show-code">Code</button>
bool         <strong>collideConnected</strong> <a class="anchor-link"
            href="#collideConnected"
            title="Permalink to RevoluteJoint.collideConnected">#</a>
        </h4>
        <div class="inherited-from">inherited from <a href="../box2d/Joint.html">Joint</a> </div><div class="doc">
<pre class="source">
collideConnected
</pre>
</div>
</div>
<div class="field inherited"><h4 id="edgeA">
<button class="show-code">Code</button>
<a href="../box2d/JointEdge.html">JointEdge</a>         <strong>edgeA</strong> <a class="anchor-link"
            href="#edgeA"
            title="Permalink to RevoluteJoint.edgeA">#</a>
        </h4>
        <div class="inherited-from">inherited from <a href="../box2d/Joint.html">Joint</a> </div><div class="doc">
<pre class="source">
edgeA
</pre>
</div>
</div>
<div class="field inherited"><h4 id="edgeB">
<button class="show-code">Code</button>
<a href="../box2d/JointEdge.html">JointEdge</a>         <strong>edgeB</strong> <a class="anchor-link"
            href="#edgeB"
            title="Permalink to RevoluteJoint.edgeB">#</a>
        </h4>
        <div class="inherited-from">inherited from <a href="../box2d/Joint.html">Joint</a> </div><div class="doc">
<pre class="source">
edgeB
</pre>
</div>
</div>
<div class="field"><h4 id="impulse">
<button class="show-code">Code</button>
final <a href="../vector_math/vec3.html">vec3</a>         <strong>impulse</strong> <a class="anchor-link"
            href="#impulse"
            title="Permalink to RevoluteJoint.impulse">#</a>
        </h4>
        <div class="doc">
<pre class="source">
impulse
</pre>
</div>
</div>
<div class="field inherited"><h4 id="invIA">
<button class="show-code">Code</button>
num         <strong>invIA</strong> <a class="anchor-link"
            href="#invIA"
            title="Permalink to RevoluteJoint.invIA">#</a>
        </h4>
        <div class="inherited-from">inherited from <a href="../box2d/Joint.html">Joint</a> </div><div class="doc">
<pre class="source">
invIA
</pre>
</div>
</div>
<div class="field inherited"><h4 id="invIB">
<button class="show-code">Code</button>
num         <strong>invIB</strong> <a class="anchor-link"
            href="#invIB"
            title="Permalink to RevoluteJoint.invIB">#</a>
        </h4>
        <div class="inherited-from">inherited from <a href="../box2d/Joint.html">Joint</a> </div><div class="doc">
<pre class="source">
invIB
</pre>
</div>
</div>
<div class="field inherited"><h4 id="invMassA">
<button class="show-code">Code</button>
num         <strong>invMassA</strong> <a class="anchor-link"
            href="#invMassA"
            title="Permalink to RevoluteJoint.invMassA">#</a>
        </h4>
        <div class="inherited-from">inherited from <a href="../box2d/Joint.html">Joint</a> </div><div class="doc">
<pre class="source">
invMassA
</pre>
</div>
</div>
<div class="field inherited"><h4 id="invMassB">
<button class="show-code">Code</button>
num         <strong>invMassB</strong> <a class="anchor-link"
            href="#invMassB"
            title="Permalink to RevoluteJoint.invMassB">#</a>
        </h4>
        <div class="inherited-from">inherited from <a href="../box2d/Joint.html">Joint</a> </div><div class="doc">
<pre class="source">
invMassB
</pre>
</div>
</div>
<div class="field inherited"><h4 id="islandFlag">
<button class="show-code">Code</button>
bool         <strong>islandFlag</strong> <a class="anchor-link"
            href="#islandFlag"
            title="Permalink to RevoluteJoint.islandFlag">#</a>
        </h4>
        <div class="inherited-from">inherited from <a href="../box2d/Joint.html">Joint</a> </div><div class="doc">
<pre class="source">
islandFlag
</pre>
</div>
</div>
<div class="field"><h4 id="jointAngle">
<button class="show-code">Code</button>
final num         <strong>jointAngle</strong> <a class="anchor-link"
            href="#jointAngle"
            title="Permalink to RevoluteJoint.jointAngle">#</a>
        </h4>
        <div class="doc">
<pre class="source">
num get jointAngle {
 final Body b1 = bodyA;
 final Body b2 = bodyB;
 return b2.sweep.angle - b1.sweep.angle - referenceAngle;
}
</pre>
</div>
</div>
<div class="field"><h4 id="jointSpeed">
<button class="show-code">Code</button>
final num         <strong>jointSpeed</strong> <a class="anchor-link"
            href="#jointSpeed"
            title="Permalink to RevoluteJoint.jointSpeed">#</a>
        </h4>
        <div class="doc">
<pre class="source">
num get jointSpeed {
 final Body b1 = bodyA;
 final Body b2 = bodyB;
 return b2.angularVelocity - b1.angularVelocity;
}
</pre>
</div>
</div>
<div class="field"><h4 id="limitEnabled">
<button class="show-code">Code</button>
bool         <strong>limitEnabled</strong> <a class="anchor-link"
            href="#limitEnabled"
            title="Permalink to RevoluteJoint.limitEnabled">#</a>
        </h4>
        <div class="doc">
<pre class="source">
bool get limitEnabled =&gt; _enableLimit;
</pre>
<pre class="source">
void set limitEnabled(bool flag) {
 bodyA.awake = true;
 bodyB.awake = true;
 _enableLimit = flag;
}
</pre>
</div>
</div>
<div class="field"><h4 id="limitState">
<button class="show-code">Code</button>
int         <strong>limitState</strong> <a class="anchor-link"
            href="#limitState"
            title="Permalink to RevoluteJoint.limitState">#</a>
        </h4>
        <div class="doc">
<pre class="source">
limitState
</pre>
</div>
</div>
<div class="field"><h4 id="localAnchor1">
<button class="show-code">Code</button>
final <a href="../vector_math/vec2.html">vec2</a>         <strong>localAnchor1</strong> <a class="anchor-link"
            href="#localAnchor1"
            title="Permalink to RevoluteJoint.localAnchor1">#</a>
        </h4>
        <div class="doc">
<pre class="source">
localAnchor1
</pre>
</div>
</div>
<div class="field"><h4 id="localAnchor2">
<button class="show-code">Code</button>
final <a href="../vector_math/vec2.html">vec2</a>         <strong>localAnchor2</strong> <a class="anchor-link"
            href="#localAnchor2"
            title="Permalink to RevoluteJoint.localAnchor2">#</a>
        </h4>
        <div class="doc">
<pre class="source">
localAnchor2
</pre>
</div>
</div>
<div class="field inherited"><h4 id="localCenterA">
<button class="show-code">Code</button>
final <a href="../vector_math/vec2.html">vec2</a>         <strong>localCenterA</strong> <a class="anchor-link"
            href="#localCenterA"
            title="Permalink to RevoluteJoint.localCenterA">#</a>
        </h4>
        <div class="inherited-from">inherited from <a href="../box2d/Joint.html">Joint</a> </div><div class="doc">
<pre class="source">
localCenterA
</pre>
</div>
</div>
<div class="field inherited"><h4 id="localCenterB">
<button class="show-code">Code</button>
final <a href="../vector_math/vec2.html">vec2</a>         <strong>localCenterB</strong> <a class="anchor-link"
            href="#localCenterB"
            title="Permalink to RevoluteJoint.localCenterB">#</a>
        </h4>
        <div class="inherited-from">inherited from <a href="../box2d/Joint.html">Joint</a> </div><div class="doc">
<pre class="source">
localCenterB
</pre>
</div>
</div>
<div class="field"><h4 id="lowerAngle">
<button class="show-code">Code</button>
num         <strong>lowerAngle</strong> <a class="anchor-link"
            href="#lowerAngle"
            title="Permalink to RevoluteJoint.lowerAngle">#</a>
        </h4>
        <div class="doc">
<pre class="source">
lowerAngle
</pre>
</div>
</div>
<div class="field"><h4 id="mass">
<button class="show-code">Code</button>
final <a href="../vector_math/mat3.html">mat3</a>         <strong>mass</strong> <a class="anchor-link"
            href="#mass"
            title="Permalink to RevoluteJoint.mass">#</a>
        </h4>
        <div class="doc">
<pre class="source">
mass
</pre>
</div>
</div>
<div class="field"><h4 id="maxMotorTorque">
<button class="show-code">Code</button>
num         <strong>maxMotorTorque</strong> <a class="anchor-link"
            href="#maxMotorTorque"
            title="Permalink to RevoluteJoint.maxMotorTorque">#</a>
        </h4>
        <div class="doc">
<pre class="source">
num get maxMotorTorque =&gt; _maxMotorTorque;
</pre>
<pre class="source">
void set maxMotorTorque(num torque) {
 bodyA.awake = true;
 bodyB.awake = true;
 _maxMotorTorque = torque;
}
</pre>
</div>
</div>
<div class="field"><h4 id="motorEnabled">
<button class="show-code">Code</button>
bool         <strong>motorEnabled</strong> <a class="anchor-link"
            href="#motorEnabled"
            title="Permalink to RevoluteJoint.motorEnabled">#</a>
        </h4>
        <div class="doc">
<pre class="source">
bool get motorEnabled =&gt; _enableMotor;
</pre>
<pre class="source">
void set motorEnabled(bool flag) {
 bodyA.awake = true;
 bodyB.awake = true;
 _enableMotor = flag;
}
</pre>
</div>
</div>
<div class="field"><h4 id="motorMass">
<button class="show-code">Code</button>
num         <strong>motorMass</strong> <a class="anchor-link"
            href="#motorMass"
            title="Permalink to RevoluteJoint.motorMass">#</a>
        </h4>
        <div class="doc">
<pre class="source">
motorMass
</pre>
</div>
</div>
<div class="field"><h4 id="motorSpeed">
<button class="show-code">Code</button>
num         <strong>motorSpeed</strong> <a class="anchor-link"
            href="#motorSpeed"
            title="Permalink to RevoluteJoint.motorSpeed">#</a>
        </h4>
        <div class="doc">
<pre class="source">
num get motorSpeed =&gt; _motorSpeed;
</pre>
<pre class="source">
void set motorSpeed(num speed) {
 bodyA.awake = true;
 bodyB.awake = true;
 _motorSpeed = speed;
}
</pre>
</div>
</div>
<div class="field"><h4 id="motorTorque">
<button class="show-code">Code</button>
final num         <strong>motorTorque</strong> <a class="anchor-link"
            href="#motorTorque"
            title="Permalink to RevoluteJoint.motorTorque">#</a>
        </h4>
        <div class="doc">
<pre class="source">
num get motorTorque =&gt; _motorImpulse;
</pre>
</div>
</div>
<div class="field"><h4 id="referenceAngle">
<button class="show-code">Code</button>
num         <strong>referenceAngle</strong> <a class="anchor-link"
            href="#referenceAngle"
            title="Permalink to RevoluteJoint.referenceAngle">#</a>
        </h4>
        <div class="doc">
<pre class="source">
referenceAngle
</pre>
</div>
</div>
<div class="field inherited"><h4 id="type">
<button class="show-code">Code</button>
int         <strong>type</strong> <a class="anchor-link"
            href="#type"
            title="Permalink to RevoluteJoint.type">#</a>
        </h4>
        <div class="inherited-from">inherited from <a href="../box2d/Joint.html">Joint</a> </div><div class="doc">
<pre class="source">
type
</pre>
</div>
</div>
<div class="field"><h4 id="upperAngle">
<button class="show-code">Code</button>
num         <strong>upperAngle</strong> <a class="anchor-link"
            href="#upperAngle"
            title="Permalink to RevoluteJoint.upperAngle">#</a>
        </h4>
        <div class="doc">
<pre class="source">
upperAngle
</pre>
</div>
</div>
<div class="field inherited"><h4 id="userData">
<button class="show-code">Code</button>
Object         <strong>userData</strong> <a class="anchor-link"
            href="#userData"
            title="Permalink to RevoluteJoint.userData">#</a>
        </h4>
        <div class="inherited-from">inherited from <a href="../box2d/Joint.html">Joint</a> </div><div class="doc">
<pre class="source">
userData
</pre>
</div>
</div>
</div>
<div>
<h3>Methods</h3>
<div class="method inherited"><h4 id="destructor">
<button class="show-code">Code</button>
void <strong>destructor</strong>() <a class="anchor-link" href="#destructor"
              title="Permalink to RevoluteJoint.destructor">#</a></h4>
<div class="inherited-from">inherited from <a href="../box2d/Joint.html">Joint</a> </div><div class="doc">
<p>Override to handle destruction of joint. </p>
<pre class="source">
void destructor() { }
</pre>
</div>
</div>
<div class="method"><h4 id="getAnchorA">
<button class="show-code">Code</button>
void <strong>getAnchorA</strong>(<a href="../vector_math/vec2.html">vec2</a> argOut) <a class="anchor-link" href="#getAnchorA"
              title="Permalink to RevoluteJoint.getAnchorA">#</a></h4>
<div class="doc">
<div class="inherited">
<p>Get the anchor point on bodyA in world coordinates. </p>
<div class="docs-inherited-from">docs inherited from <a href="../box2d/Joint.html">Joint</a> </div></div>
<pre class="source">
void getAnchorA(vec2 argOut) {
 bodyA.getWorldPointToOut(localAnchor1, argOut);
}
</pre>
</div>
</div>
<div class="method"><h4 id="getAnchorB">
<button class="show-code">Code</button>
void <strong>getAnchorB</strong>(<a href="../vector_math/vec2.html">vec2</a> argOut) <a class="anchor-link" href="#getAnchorB"
              title="Permalink to RevoluteJoint.getAnchorB">#</a></h4>
<div class="doc">
<div class="inherited">
<p>Get the anchor point on bodyB in world coordinates. </p>
<div class="docs-inherited-from">docs inherited from <a href="../box2d/Joint.html">Joint</a> </div></div>
<pre class="source">
void getAnchorB(vec2 argOut) {
 bodyB.getWorldPointToOut(localAnchor2, argOut);
}
</pre>
</div>
</div>
<div class="method"><h4 id="getReactionForce">
<button class="show-code">Code</button>
void <strong>getReactionForce</strong>(num inv_dt, <a href="../vector_math/vec2.html">vec2</a> argOut) <a class="anchor-link" href="#getReactionForce"
              title="Permalink to RevoluteJoint.getReactionForce">#</a></h4>
<div class="doc">
<div class="inherited">
<p>Get the reaction force on body2 at the joint anchor in Newtons. </p>
<div class="docs-inherited-from">docs inherited from <a href="../box2d/Joint.html">Joint</a> </div></div>
<pre class="source">
void getReactionForce(num inv_dt, vec2 argOut) {
 argOut.setComponents(impulse.x, impulse.y).scale(inv_dt);
}
</pre>
</div>
</div>
<div class="method"><h4 id="getReactionTorque">
<button class="show-code">Code</button>
num <strong>getReactionTorque</strong>(num inv_dt) <a class="anchor-link" href="#getReactionTorque"
              title="Permalink to RevoluteJoint.getReactionTorque">#</a></h4>
<div class="doc">
<div class="inherited">
<p>Get the reaction torque on body2 in N*m. </p>
<div class="docs-inherited-from">docs inherited from <a href="../box2d/Joint.html">Joint</a> </div></div>
<pre class="source">
num getReactionTorque(num inv_dt) {
 return inv_dt * impulse.z;
}
</pre>
</div>
</div>
<div class="method"><h4 id="initVelocityConstraints">
<button class="show-code">Code</button>
void <strong>initVelocityConstraints</strong>(<a href="../box2d/TimeStep.html">TimeStep</a> time_step) <a class="anchor-link" href="#initVelocityConstraints"
              title="Permalink to RevoluteJoint.initVelocityConstraints">#</a></h4>
<div class="doc">
<pre class="source">
void initVelocityConstraints(TimeStep time_step) {
 final Body b1 = bodyA;
 final Body b2 = bodyB;

 if (_enableMotor || _enableLimit) {
   // You cannot create a rotation limit between bodies that
   // both have fixed rotation.
   assert (b1.invInertia &gt; 0.0 || b2.invInertia &gt; 0.0);
 }

 // Compute the effective mass matrix.
 final vec2 r1 = localAnchor1 - b1.localCenter;
 final vec2 r2 = localAnchor2 - b2.localCenter;
 b1.originTransform.rotation.transform(r1);
 b2.originTransform.rotation.transform(r2);

 num m1 = b1.invMass, m2 = b2.invMass;
 num i1 = b1.invInertia, i2 = b2.invInertia;

 mass.col0.x = m1 + m2 + r1.y * r1.y * i1 + r2.y * r2.y * i2;
 mass.col1.x = -r1.y * r1.x * i1 - r2.y * r2.x * i2;
 mass.col2.x = -r1.y * i1 - r2.y * i2;
 mass.col0.y = mass.col1.x;
 mass.col1.y = m1 + m2 + r1.x * r1.x * i1 + r2.x * r2.x * i2;
 mass.col2.y = r1.x * i1 + r2.x * i2;
 mass.col0.z = mass.col2.x;
 mass.col1.z = mass.col2.y;
 mass.col2.z = i1 + i2;

 motorMass = i1 + i2;
 if (motorMass &gt; 0.0) {
   motorMass = 1.0 / motorMass;
 }

 if (_enableMotor == false) {
   _motorImpulse = 0.0;
 }

 if (_enableLimit) {
   num jointAngle = b2.sweep.angle - b1.sweep.angle - referenceAngle;
   if ((upperAngle - lowerAngle).abs() &lt; 2.0 * Settings.ANGULAR_SLOP) {
     limitState = LimitState.EQUAL;
   }
   else if (jointAngle &lt;= lowerAngle) {
     if (limitState != LimitState.AT_LOWER) {
       impulse.z = 0.0;
     }
     limitState = LimitState.AT_LOWER;
   }
   else if (jointAngle &gt;= upperAngle) {
     if (limitState != LimitState.AT_UPPER) {
       impulse.z = 0.0;
     }
     limitState = LimitState.AT_UPPER;
   }
   else {
     limitState = LimitState.INACTIVE;
     impulse.z = 0.0;
   }
 }
 else {
   limitState = LimitState.INACTIVE;
 }

 if (time_step.warmStarting) {
   // Scale impulses to support a variable time time_step.
   impulse.scale(time_step.dtRatio);
   _motorImpulse *= time_step.dtRatio;

   vec2 P = new vec2.copy(impulse.xy);

   vec2 temp = new vec2.copy(P);
   temp.scale(m1);
   b1.linearVelocity.sub(temp);
   b1.angularVelocity -= i1 * (cross(r1, P) + _motorImpulse + impulse.z);

   temp.copyFrom(P).scale(m2);
   b2.linearVelocity.add(temp);
   b2.angularVelocity += i2 * (cross(r2, P) + _motorImpulse + impulse.z);

 } else {
   impulse.splat(0.0);
   _motorImpulse = 0.0;
 }
}
</pre>
</div>
</div>
<div class="method"><h4 id="setLimits">
<button class="show-code">Code</button>
void <strong>setLimits</strong>(num lower, num upper) <a class="anchor-link" href="#setLimits"
              title="Permalink to RevoluteJoint.setLimits">#</a></h4>
<div class="doc">
<pre class="source">
void setLimits(final num lower, final num upper) {
 assert (lower &lt;= upper);
 bodyA.awake = true;
 bodyB.awake = true;
 lowerAngle = lower;
 upperAngle = upper;
}
</pre>
</div>
</div>
<div class="method"><h4 id="solvePositionConstraints">
<button class="show-code">Code</button>
bool <strong>solvePositionConstraints</strong>(num baumgarte) <a class="anchor-link" href="#solvePositionConstraints"
              title="Permalink to RevoluteJoint.solvePositionConstraints">#</a></h4>
<div class="doc">
<div class="inherited">
<p>This returns true if the position errors are within tolerance. </p>
<div class="docs-inherited-from">docs inherited from <a href="../box2d/Joint.html">Joint</a> </div></div>
<pre class="source">
bool solvePositionConstraints(num baumgarte) {
 final Body b1 = bodyA;
 final Body b2 = bodyB;

 num angularError = 0.0;
 num positionError = 0.0;

 // Solve angular limit constraint.
 if (_enableLimit &amp;&amp; limitState != LimitState.INACTIVE) {
   num angle = b2.sweep.angle - b1.sweep.angle - referenceAngle;
   num limitImpulse = 0.0;

   if (limitState == LimitState.EQUAL) {
     // Prevent large angular corrections
     num C = clamp(angle - lowerAngle, -Settings.MAX_ANGULAR_CORRECTION, Settings.MAX_ANGULAR_CORRECTION);
     limitImpulse = -motorMass * C;
     angularError = C.abs();
   } else if (limitState == LimitState.AT_LOWER) {
     num C = angle - lowerAngle;
     angularError = -C;

     // Prevent large angular corrections and allow some slop.
     C = clamp(C + Settings.ANGULAR_SLOP, -Settings.MAX_ANGULAR_CORRECTION, 0.0);
     limitImpulse = -motorMass * C;
   } else if (limitState == LimitState.AT_UPPER) {
     num C = angle - upperAngle;
     angularError = C;

     // Prevent large angular corrections and allow some slop.
     C = clamp(C - Settings.ANGULAR_SLOP, 0.0, Settings.MAX_ANGULAR_CORRECTION);
     limitImpulse = -motorMass * C;
   }

   b1.sweep.angle -= b1.invInertia * limitImpulse;
   b2.sweep.angle += b2.invInertia * limitImpulse;

   b1.synchronizeTransform();
   b2.synchronizeTransform();
 }

 // Solve point-to-point constraint.
 {
   vec2 imp = new vec2.zero();

   final vec2 r1 = localAnchor1 - b1.localCenter;
   final vec2 r2 = localAnchor2 - b2.localCenter;
   b1.originTransform.rotation.transform(r1);
   b2.originTransform.rotation.transform(r2);

   final vec2 C = b2.sweep.center + r2 - (b1.sweep.center + r1);
   positionError = C.length;

   num invMass1 = b1.invMass, invMass2 = b2.invMass;
   num invI1 = b1.invInertia, invI2 = b2.invInertia;

   // Handle large detachment.
   final num k_allowedStretch = 10.0 * Settings.LINEAR_SLOP;
   if (C.length2 &gt; k_allowedStretch * k_allowedStretch) {
     vec2 u = new vec2.zero();

     // Use a particle solution (no rotation).
     num m = invMass1 + invMass2;
     if (m &gt; 0.0) {
       m = 1.0 / m;
     }
     imp.copyFrom(C).negate().scale(m);
     final num k_beta = 0.5;
     // using u as temp variable
     u.copyFrom(imp).scale(k_beta * invMass1);
     b1.sweep.center.sub(u);
     u.copyFrom(imp).scale(k_beta * invMass2);
     b2.sweep.center.add(u);

     C.copyFrom(b2.sweep.center).add(r2);
     C.sub(b1.sweep.center).sub(r1);
   }

   mat2 K1 = new mat2.zero();
   K1.col0.x = invMass1 + invMass2;
   K1.col1.x = 0.0;
   K1.col0.y = 0.0;
   K1.col1.y = invMass1 + invMass2;

   mat2 K2 = new mat2.zero();
   K2.col0.x = invI1 * r1.y * r1.y;
   K2.col1.x = -invI1 * r1.x * r1.y;
   K2.col0.y = -invI1 * r1.x * r1.y;
   K2.col1.y = invI1 * r1.x * r1.x;

   mat2 K3 = new mat2.zero();
   K3.col0.x = invI2 * r2.y * r2.y;
   K3.col1.x = -invI2 * r2.x * r2.y;
   K3.col0.y = -invI2 * r2.x * r2.y;
   K3.col1.y = invI2 * r2.x * r2.x;

   K1.add(K2).add(K3);
   imp = MathBox.solve22(K1, C.negate()); // just leave c negated

   // using C as temp variable
   C.copyFrom(imp).scale(b1.invMass);
   b1.sweep.center.sub(C);
   b1.sweep.angle -= b1.invInertia * cross(r1, imp);

   C.copyFrom(imp).scale(b2.invMass);
   b2.sweep.center.add(C);
   b2.sweep.angle += b2.invInertia * cross(r2, imp);

   b1.synchronizeTransform();
   b2.synchronizeTransform();
 }

 return positionError &lt;= Settings.LINEAR_SLOP &amp;&amp; angularError &lt;=
     Settings.ANGULAR_SLOP;
}
</pre>
</div>
</div>
<div class="method"><h4 id="solveVelocityConstraints">
<button class="show-code">Code</button>
void <strong>solveVelocityConstraints</strong>(<a href="../box2d/TimeStep.html">TimeStep</a> time_step) <a class="anchor-link" href="#solveVelocityConstraints"
              title="Permalink to RevoluteJoint.solveVelocityConstraints">#</a></h4>
<div class="doc">
<pre class="source">
void solveVelocityConstraints(final TimeStep time_step) {
 final Body b1 = bodyA;
 final Body b2 = bodyB;

 final vec2 v1 = b1.linearVelocity;
 num w1 = b1.angularVelocity;
 final vec2 v2 = b2.linearVelocity;
 num w2 = b2.angularVelocity;

 num m1 = b1.invMass, m2 = b2.invMass;
 num i1 = b1.invInertia, i2 = b2.invInertia;

 // Solve motor constraint.
 if (_enableMotor &amp;&amp; limitState != LimitState.EQUAL) {
   num Cdot = w2 - w1 - _motorSpeed;
   num imp = motorMass * (-Cdot);
   num oldImpulse = _motorImpulse;
   num maxImpulse = time_step.dt * _maxMotorTorque;
   _motorImpulse = clamp(_motorImpulse + imp, -maxImpulse, maxImpulse);
   imp = _motorImpulse - oldImpulse;

   w1 -= i1 * imp;
   w2 += i2 * imp;
 }

 vec2 temp = new vec2.zero();

 // Solve limit constraint.
 if (_enableLimit &amp;&amp; limitState != LimitState.INACTIVE) {

   final vec2 r1 = localAnchor1 - b1.localCenter;
   final vec2 r2 = localAnchor2 - b2.localCenter;
   b1.originTransform.rotation.transform(r1);
   b2.originTransform.rotation.transform(r2);

   // Solve point-to-point constraint
   cross(w1, r1, temp);
   final vec2 Cdot1 = cross(w2, r2);
   Cdot1.add(v2).sub(v1).sub(temp);
   num Cdot2 = w2 - w1;
   vec3 Cdot = new vec3(Cdot1.x, Cdot1.y, Cdot2);

   vec3 imp = MathBox.solve33(mass, Cdot.negate());

   if (limitState == LimitState.EQUAL) {
     impulse.add(imp);
   }
   else if (limitState == LimitState.AT_LOWER) {
     num newImpulse = impulse.z + imp.z;
     if (newImpulse &lt; 0.0) {
       temp = MathBox.solve22(mass, Cdot1.negate());
       imp.x = temp.x;
       imp.y = temp.y;
       imp.z = -impulse.z;
       impulse.x += temp.x;
       impulse.y += temp.y;
       impulse.z = 0.0;
     }
   } else if (limitState == LimitState.AT_UPPER) {
     num newImpulse = impulse.z + imp.z;
     if (newImpulse &gt; 0.0) {
       temp = MathBox.solve22(mass, Cdot1.negate());
       imp.x = temp.x;
       imp.y = temp.y;
       imp.z = -impulse.z;
       impulse.x += temp.x;
       impulse.y += temp.y;
       impulse.z = 0.0;
     }
   }
   final vec2 P = new vec2.copy(imp.xy);

   temp.copyFrom(P).scale(m1);
   v1.sub(temp);
   w1 -= i1 * (cross(r1, P) + imp.z);

   temp.copyFrom(P).scale(m2);
   v2.add(temp);
   w2 += i2 * (cross(r2, P) + imp.z);

 } else {
   final vec2 r1 = localAnchor1 - b1.localCenter;
   final vec2 r2 = localAnchor2 - b2.localCenter;
   b1.originTransform.rotation.transform(r1);
   b2.originTransform.rotation.transform(r2);

   // Solve point-to-point constraint
   cross(w1, r1, temp);
   vec2 Cdot = cross(w2, r2);
   Cdot.add(v2).sub(v1).sub(temp);
   vec2 imp = MathBox.solve22(mass, Cdot.negate()); // just leave negated

   impulse.x += imp.x;
   impulse.y += imp.y;

   temp.copyFrom(imp).scale(m1);
   v1.sub(temp);
   w1 -= i1 * cross(r1, imp);

   temp.copyFrom(imp).scale(m2);
   v2.add(temp);
   w2 += i2 * cross(r2, imp);
 }

 b1.angularVelocity = w1;
 b2.angularVelocity = w2;
}
</pre>
</div>
</div>
</div>
        </div>
        <div class="clear"></div>
        </div>
        <div class="footer">
          
        </div>
        <script async src="../client-live-nav.js"></script>
        </body></html>
        
